package com.christina.controller.api.v1;

import com.christina.service.application.ChristinaApplicationService;
import com.christina.service.application.model.UnifiedRequest;
import com.christina.service.application.model.UnifiedResponse;
import com.christina.utils.Result;
import com.christina.utils.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Christina统一API控制器
 * 这是新架构的主要入口，所有请求都通过这里进行统一处理
 * 
 * @author Christina
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/christina")
@Tag(name = "Christina统一API", description = "基于AI引擎的统一智能助手接口")
public class ChristinaController {

    private final ChristinaApplicationService applicationService;
    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    public ChristinaController(ChristinaApplicationService applicationService) {
        this.applicationService = applicationService;
    }

    /**
     * 统一智能处理接口
     * 支持所有类型的用户请求：聊天、出行规划、任务管理等
     */
    @PostMapping("/process")
    @PreAuthorize("isAuthenticated()")
    @Operation(summary = "统一智能处理", description = "AI自动识别意图并路由到相应服务")
    public Result<UnifiedResponse> processRequest(@RequestBody ProcessRequest request) {
        Long userId = SecurityUtils.getCurrentUserId();
        String sessionId = request.getSessionId() != null ? request.getSessionId() : generateSessionId();
        
        log.info("收到统一处理请求: userId={}, sessionId={}, input={}", 
            userId, sessionId, request.getUserInput());
        
        try {
            // 构建统一请求
            UnifiedRequest unifiedRequest = UnifiedRequest.builder()
                .userId(userId)
                .sessionId(sessionId)
                .userInput(request.getUserInput())
                .requestType(UnifiedRequest.RequestType.TEXT)
                .requestTime(LocalDateTime.now())
                .extraParameters(request.getExtraParameters())
                .build();
            
            // 处理请求
            UnifiedResponse response = applicationService.processRequest(unifiedRequest);
            
            return Result.success("处理成功", response);
            
        } catch (Exception e) {
            log.error("统一处理失败: userId={}", userId, e);
            return Result.error(500, "处理失败: " + e.getMessage());
        }
    }

    /**
     * 流式智能处理接口
     * 实时返回处理过程和结果
     */
    @PostMapping(value = "/process/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @PreAuthorize("isAuthenticated()")
    @Operation(summary = "流式智能处理", description = "实时返回AI处理过程")
    public SseEmitter processRequestStream(@RequestBody ProcessRequest request) {
        Long userId = SecurityUtils.getCurrentUserId();
        String sessionId = request.getSessionId() != null ? request.getSessionId() : generateSessionId();
        
        log.info("收到流式处理请求: userId={}, sessionId={}", userId, sessionId);
        
        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
        
        executorService.submit(() -> {
            try {
                // 发送处理开始信号
                emitter.send(SseEmitter.event()
                    .name("status")
                    .data("🤖 Christina正在分析您的需求..."));
                
                Thread.sleep(500);
                
                // 发送意图识别状态
                emitter.send(SseEmitter.event()
                    .name("status")
                    .data("🧠 正在识别您的意图..."));
                
                Thread.sleep(800);
                
                // 发送决策状态
                emitter.send(SseEmitter.event()
                    .name("status")
                    .data("⚡ 正在制定处理方案..."));
                
                Thread.sleep(600);
                
                // 发送执行状态
                emitter.send(SseEmitter.event()
                    .name("status")
                    .data("🚀 正在执行相关服务..."));
                
                // 构建并处理请求
                UnifiedRequest unifiedRequest = UnifiedRequest.builder()
                    .userId(userId)
                    .sessionId(sessionId)
                    .userInput(request.getUserInput())
                    .requestType(UnifiedRequest.RequestType.TEXT)
                    .requestTime(LocalDateTime.now())
                    .extraParameters(request.getExtraParameters())
                    .build();
                
                UnifiedResponse response = applicationService.processRequest(unifiedRequest);
                
                // 发送最终结果
                emitter.send(SseEmitter.event()
                    .name("result")
                    .data(response));
                
                emitter.send(SseEmitter.event()
                    .name("status")
                    .data("✅ 处理完成！"));
                
                emitter.complete();
                
            } catch (Exception e) {
                log.error("流式处理失败", e);
                try {
                    emitter.send(SseEmitter.event()
                        .name("error")
                        .data("❌ 处理失败: " + e.getMessage()));
                } catch (IOException ioException) {
                    log.error("发送错误信息失败", ioException);
                }
                emitter.completeWithError(e);
            }
        });
        
        return emitter;
    }

    /**
     * 获取会话上下文
     */
    @GetMapping("/context/{sessionId}")
    @PreAuthorize("isAuthenticated()")
    @Operation(summary = "获取会话上下文", description = "获取指定会话的上下文信息")
    public Result<Object> getSessionContext(@PathVariable String sessionId) {
        Long userId = SecurityUtils.getCurrentUserId();
        
        try {
            // 这里可以调用上下文管理器获取会话信息
            log.info("获取会话上下文: userId={}, sessionId={}", userId, sessionId);
            
            return Result.success("获取成功", "会话上下文信息");
            
        } catch (Exception e) {
            log.error("获取会话上下文失败", e);
            return Result.error(500, "获取失败: " + e.getMessage());
        }
    }

    /**
     * 清除会话上下文
     */
    @DeleteMapping("/context/{sessionId}")
    @PreAuthorize("isAuthenticated()")
    @Operation(summary = "清除会话上下文", description = "清除指定会话的上下文信息")
    public Result<String> clearSessionContext(@PathVariable String sessionId) {
        Long userId = SecurityUtils.getCurrentUserId();
        
        try {
            log.info("清除会话上下文: userId={}, sessionId={}", userId, sessionId);
            
            return Result.success("清除成功");
            
        } catch (Exception e) {
            log.error("清除会话上下文失败", e);
            return Result.error(500, "清除失败: " + e.getMessage());
        }
    }

    /**
     * 健康检查
     */
    @GetMapping("/health")
    @Operation(summary = "健康检查", description = "检查Christina服务状态")
    public Result<HealthStatus> health() {
        try {
            HealthStatus status = HealthStatus.builder()
                .status("UP")
                .timestamp(LocalDateTime.now())
                .version("1.0.0")
                .aiEngineStatus("ACTIVE")
                .build();
            
            return Result.success("服务正常", status);
            
        } catch (Exception e) {
            log.error("健康检查失败", e);
            return Result.error(500, "服务异常");
        }
    }

    /**
     * 生成会话ID
     */
    private String generateSessionId() {
        return "SESSION_" + UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 处理请求DTO
     */
    @lombok.Data
    public static class ProcessRequest {
        private String userInput;
        private String sessionId;
        private java.util.Map<String, Object> extraParameters;
    }

    /**
     * 健康状态DTO
     */
    @lombok.Data
    @lombok.Builder
    public static class HealthStatus {
        private String status;
        private LocalDateTime timestamp;
        private String version;
        private String aiEngineStatus;
    }
}